package rad.framework.mda.properties;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import rad.framework.uml2.uml.edit.providers.ElementItemProvider;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.PropertyDescriptor;
import org.eclipse.emf.edit.ui.provider.PropertySource;
import org.eclipse.gef.EditPart;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.eclipse.uml2.common.edit.provider.IItemQualifiedTextProvider;


/**
 * @author boudyacho
 *
 */
public class StereotypeAttributesSection extends AdvancedPropertySection {

	//sous classe StereotypeAdapterFactoryContentProvider
	protected static class StereotypeAdapterFactoryContentProvider extends AdapterFactoryContentProvider {

		/**
		 * Constructeur
		 * 
		 * @param adapterFactory
		 */
		protected StereotypeAdapterFactoryContentProvider(AdapterFactory adapterFactory) {
			super(adapterFactory);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider#getPropertySource(java.lang.Object)
		 */
		public IPropertySource getPropertySource(Object object) {
			Object copiedObject = object;
			return super.getPropertySource(copiedObject);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider#createPropertySource(java.lang.Object, org.eclipse.emf.edit.provider.IItemPropertySource)
		 */
		protected IPropertySource createPropertySource(Object object,
				IItemPropertySource itemPropertySource) {
			return new StereotypePropertySource(object, itemPropertySource);
		}
	}


	//sous classe StereotypePropertySource
	protected static class StereotypePropertySource extends PropertySource {

		private List stereotypeApplicationItemPropertyDescriptors = null;

		/**
		 * Constructeur
		 * 
		 * @param object
		 * @param itemPropertySource
		 */
		protected StereotypePropertySource(Object object,IItemPropertySource itemPropertySource) {
			super(object, itemPropertySource);
		}


		/* (non-Javadoc)
		 * @see org.eclipse.emf.edit.ui.provider.PropertySource#createPropertyDescriptor(org.eclipse.emf.edit.provider.IItemPropertyDescriptor)
		 */
		protected IPropertyDescriptor createPropertyDescriptor(IItemPropertyDescriptor itemPropertyDescriptor) {
			return new StereotypePropertyDescriptor(object,itemPropertyDescriptor);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.emf.edit.ui.provider.PropertySource#getPropertyDescriptors()
		 */
		public IPropertyDescriptor[] getPropertyDescriptors() {
			List propertyDescriptors = new ArrayList();
			if (itemPropertySource instanceof ElementItemProvider) {
				stereotypeApplicationItemPropertyDescriptors = ((ElementItemProvider) itemPropertySource).getStereotypeApplicationPropertyDescriptors(object);
				if (stereotypeApplicationItemPropertyDescriptors != null) {
					for (Iterator i = stereotypeApplicationItemPropertyDescriptors.iterator(); i.hasNext();) {
						propertyDescriptors.add(createPropertyDescriptor((IItemPropertyDescriptor) i.next()));
					}
				}
			}
			return (IPropertyDescriptor[]) propertyDescriptors.toArray(new IPropertyDescriptor[propertyDescriptors.size()]);
		}

		/**
		 * Retourne un descripteur des propriete de l'idem ayant pour id propertyId
		 * 
		 * @param propertyId
		 * @return IItemPropertyDescriptor
		 */
		protected IItemPropertyDescriptor getItemPropertyDescriptor(Object propertyId) {
			IItemPropertyDescriptor itemPropertyDescriptor = itemPropertySource.getPropertyDescriptor(object, propertyId);
			return itemPropertyDescriptor == null && itemPropertySource instanceof ElementItemProvider ? ((ElementItemProvider) itemPropertySource).getStereotypeApplicationPropertyDescriptor(object,propertyId): itemPropertyDescriptor;
		}


		/* (non-Javadoc)
		 * @see org.eclipse.emf.edit.ui.provider.PropertySource#getPropertyValue(java.lang.Object)
		 */
		public Object getPropertyValue(Object propertyId) {
			return getItemPropertyDescriptor(propertyId).getPropertyValue(object);
		}


		/* (non-Javadoc)
		 * @see org.eclipse.emf.edit.ui.provider.PropertySource#isPropertySet(java.lang.Object)
		 */
		public boolean isPropertySet(Object propertyId) {
			return getItemPropertyDescriptor(propertyId).isPropertySet(object);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.emf.edit.ui.provider.PropertySource#resetPropertyValue(java.lang.Object)
		 */
		public void resetPropertyValue(Object propertyId) {
			getItemPropertyDescriptor(propertyId).resetPropertyValue(object);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.emf.edit.ui.provider.PropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
		 */
		public void setPropertyValue(Object propertyId, Object value) {
			getItemPropertyDescriptor(propertyId).setPropertyValue(object,
					value);
		}

	}


	//sous classe StereotypePropertyDescriptor
	protected static class StereotypePropertyDescriptor extends PropertyDescriptor {

		/**
		 * Constructeur
		 * 
		 * @param object
		 * @param itemPropertyDescriptor
		 */
		protected StereotypePropertyDescriptor(Object object,IItemPropertyDescriptor itemPropertyDescriptor) {
			super(object, itemPropertyDescriptor);
		}


		/* (non-Javadoc)
		 * @see org.eclipse.emf.edit.ui.provider.PropertyDescriptor#getEditLabelProvider()
		 */
		protected ILabelProvider getEditLabelProvider() {
			final ILabelProvider editLabelProvider = super.getEditLabelProvider();
			return new LabelProvider() {
				public String getText(Object element) {
					return itemPropertyDescriptor instanceof IItemQualifiedTextProvider ? ((IItemQualifiedTextProvider) itemPropertyDescriptor)
							.getQualifiedText(element)
							: editLabelProvider.getText(element);
				}
				public Image getImage(Object element) {
					return editLabelProvider.getImage(element);
				}
			};
		}
	}

	public void createControls(Composite parent,TabbedPropertySheetPage tabbedPropertySheetPage) {
		super.createControls(parent, tabbedPropertySheetPage);
		page.setPropertySourceProvider(new StereotypeAdapterFactoryContentProvider(Activator.getDefault().getItemProvidersAdapterFactory()));
	}
}
